home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 39 / Amiga Format CD39 (1999-04-13)(Future Publishing)(GB)[!][issue 1999-05].iso / -seriously_amiga- / graphics / mpeg2decode / src / systems.c < prev    next >
C/C++ Source or Header  |  1999-03-02  |  6KB  |  270 lines

  1. /* systems.c, systems-specific routines                                 */
  2.  
  3. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  4.  
  5. /*
  6.  * Disclaimer of Warranty
  7.  *
  8.  * These software programs are available to the user without any license fee or
  9.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  10.  * any and all warranties, whether express, implied, or statuary, including any
  11.  * implied warranties or merchantability or of fitness for a particular
  12.  * purpose.  In no event shall the copyright-holder be liable for any
  13.  * incidental, punitive, or consequential damages of any kind whatsoever
  14.  * arising from the use of these programs.
  15.  *
  16.  * This disclaimer of warranty extends to the user of these programs and user's
  17.  * customers, employees, agents, transferees, successors, and assigns.
  18.  *
  19.  * The MPEG Software Simulation Group does not represent or warrant that the
  20.  * programs furnished hereunder are free of infringement of any third-party
  21.  * patents.
  22.  *
  23.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  24.  * are subject to royalty fees to patent holders.  Many of these patents are
  25.  * general enough such that they are unavoidable regardless of implementation
  26.  * design.
  27.  *
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32.  
  33. #include "config.h"
  34. #include "global.h"
  35. #include "audio.h"
  36.  
  37. /* initialize buffer, call once before first getbits or showbits */
  38.  
  39. /* parse system layer, ignore everything we don't need */
  40. void Next_Packet()
  41. {
  42.   unsigned int code;
  43.   int l;
  44.  
  45.   for(;;)
  46.   {
  47.     code = Get_Long();
  48.  
  49.     /* remove system layer byte stuffing */
  50.     while ((code & 0xffffff00) != 0x100)
  51.       code = (code<<8) | Get_Byte();
  52.  
  53.     switch(code)
  54.     {
  55.     case PACK_START_CODE: /* pack header */
  56.       /* skip pack header (system_clock_reference and mux_rate) */
  57.       ld->Rdptr += 8;
  58.       break;
  59.     case VIDEO_ELEMENTARY_STREAM:   
  60.       code = Get_Word();             /* packet_length */
  61.       ld->Rdmax = ld->Rdptr + code;
  62.  
  63.       code = Get_Byte();
  64.  
  65.       if((code>>6)==0x02)
  66.       {
  67.         ld->Rdptr++;
  68.         code=Get_Byte();  /* parse PES_header_data_length */
  69.         ld->Rdptr+=code;    /* advance pointer by PES_header_data_length */
  70.         printf("MPEG-2 PES packet\n");
  71.         return;
  72.       }
  73.       else if(code==0xff)
  74.       {
  75.         /* parse MPEG-1 packet header */
  76.         while((code=Get_Byte())== 0xFF);
  77.       }
  78.        
  79.       /* stuffing bytes */
  80.       if(code>=0x40)
  81.       {
  82.         if(code>=0x80)
  83.         {
  84.           fprintf(stderr,"Error in packet header\n");
  85.           exit(1);
  86.         }
  87.         /* skip STD_buffer_scale */
  88.         ld->Rdptr++;
  89.         code = Get_Byte();
  90.       }
  91.  
  92.       if(code>=0x30)
  93.       {
  94.         if(code>=0x40)
  95.         {
  96.           fprintf(stderr,"Error in packet header\n");
  97.           exit(1);
  98.         }
  99.         /* skip presentation and decoding time stamps */
  100.         ld->Rdptr += 9;
  101.       }
  102.       else if(code>=0x20)
  103.       {
  104.         /* skip presentation time stamps */
  105.         ld->Rdptr += 4;
  106.       }
  107.       else if(code!=0x0f)
  108.       {
  109.         fprintf(stderr,"Error in packet header\n");
  110.         exit(1);
  111.       }
  112.       return;
  113.     case ISO_END_CODE: /* end */
  114.       /* simulate a buffer full of sequence end codes */
  115.       l = 0;
  116.       while (l<2048)
  117.       {
  118.         ld->Rdbfr[l++] = SEQUENCE_END_CODE>>24;
  119.         ld->Rdbfr[l++] = SEQUENCE_END_CODE>>16;
  120.         ld->Rdbfr[l++] = SEQUENCE_END_CODE>>8;
  121.         ld->Rdbfr[l++] = SEQUENCE_END_CODE&0xff;
  122.       }
  123.       ld->Rdptr = ld->Rdbfr;
  124.       ld->Rdmax = ld->Rdbfr + 2048;
  125.       return;
  126.     case AUDIO_STREAM_0: /* audio part of the stream */
  127.     if(Enable_Sound)
  128.     {
  129.           code = Get_Word();             /* packet_length */
  130.           ld->Rdmax = ld->Rdptr + code;
  131.  
  132.           code = Get_Byte();
  133.  
  134.           if((code>>6)==0x02)
  135.           {
  136.             ld->Rdptr++;
  137.             code=Get_Byte();  /* parse PES_header_data_length */
  138.             ld->Rdptr+=code;    /* advance pointer by PES_header_data_length */
  139.             printf("MPEG-2 PES packet\n");
  140.             return;
  141.           }
  142.           else if(code==0xff)
  143.           {
  144.             /* parse MPEG-1 packet header */
  145.             while((code=Get_Byte())== 0xFF);
  146.           }
  147.        
  148.           /* stuffing bytes */
  149.           if(code>=0x40)
  150.           {
  151.             if(code>=0x80)
  152.             {
  153.               fprintf(stderr,"Error in packet header\n");
  154.               exit(1);
  155.             }
  156.             /* skip STD_buffer_scale */
  157.             ld->Rdptr++;
  158.             code = Get_Byte();
  159.           }
  160.  
  161.           if(code>=0x30)
  162.           {
  163.             if(code>=0x40)
  164.             {
  165.               fprintf(stderr,"Error in packet header\n");
  166.               exit(1);
  167.             }
  168.             /* skip presentation and decoding time stamps */
  169.             ld->Rdptr += 9;
  170.           }
  171.           else if(code>=0x20)
  172.           {
  173.             /* skip presentation time stamps */
  174.             ld->Rdptr += 4;
  175.           }
  176.           else if(code!=0x0f)
  177.           {
  178.             fprintf(stderr,"Error in packet header\n");
  179.             exit(1);
  180.           }
  181.  
  182.         code = ld -> Rdmax - ld -> Rdptr;
  183.  
  184.         /* feed audio-buffer with data */
  185.  
  186. #ifdef STORM
  187.         while((code--)>0) audio_feedbuffer((void *)Get_Byte());
  188. #else
  189.         while((code--)>0) audio_feedbuffer(Get_Byte());
  190. #endif
  191.     break;
  192.     }
  193.     default:
  194.       if(code>=SYSTEM_START_CODE)
  195.       {
  196.         /* skip system headers and non-video packets*/
  197.  
  198.         code = Get_Word();
  199.         ld->Rdptr += code;
  200.       }
  201.       else
  202.       {
  203.         fprintf(stderr,"Unexpected startcode %08x in system layer\n",code);
  204.         exit(1);
  205.       }
  206.       break;
  207.     }
  208.   }
  209. }
  210.  
  211.  
  212.  
  213. void Flush_Buffer32()
  214. {
  215.   int Incnt;
  216.  
  217.   ld->Bfr = 0;
  218.  
  219.   Incnt = ld->Incnt;
  220.   Incnt -= 32;
  221.  
  222.   if (System_Stream_Flag && (ld->Rdptr >= ld->Rdmax-4))
  223.   {
  224.     while (Incnt <= 24)
  225.     {
  226.       if (ld->Rdptr >= ld->Rdmax)
  227.         Next_Packet();
  228.       ld->Bfr |= Get_Byte() << (24 - Incnt);
  229.       Incnt += 8;
  230.     }
  231.   }
  232.   else
  233.   {
  234.     while (Incnt <= 24)
  235.     {
  236.       if (ld->Rdptr >= ld->Rdbfr+2048)
  237.         Fill_Buffer();
  238.       ld->Bfr |= *ld->Rdptr++ << (24 - Incnt);
  239.       Incnt += 8;
  240.     }
  241.   }
  242.   ld->Incnt = Incnt;
  243.  
  244. #ifdef VERIFY 
  245.   ld->Bitcnt += 32;
  246. #endif /* VERIFY */
  247. }
  248.  
  249.  
  250. unsigned int Get_Bits32()
  251. {
  252.   unsigned int l;
  253.  
  254.   l = Show_Bits(32);
  255.   Flush_Buffer32();
  256.  
  257.   return l;
  258. }
  259.  
  260.  
  261. int Get_Long()
  262. {
  263.   int i;
  264.  
  265.   i = Get_Word();
  266.   return (i<<16) | Get_Word();
  267. }
  268.  
  269.  
  270.